package controller;

import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JOptionPane;

import logger.LogLevel;
import logger.SimpleLogger;
import model.CityModel;
import model.CountryModel;
import model.Model;
import util.Config;
import util.Debug;
import view.ViewInterface;

/**
 * Wetter-Control-Objekt
 * 
 * @author Bernd Taube
 * @author Jakobus Boettcher
 * @version 1.0
 * 
 */
public class Controller {

	// Instanz-Variablen
    public Model model;
    protected Object itemArgument;

    // Liste der Views
    private ArrayList<ViewInterface> viewList = new ArrayList<ViewInterface>();
    
    // Liste der Actions
    private ArrayList<MyActionListener> actionList = new ArrayList<MyActionListener>();
    
	/**
	 * Konstruktor
	 */
	public Controller() {
		
		try {
			this.model = new Model();
		} catch (Exception e) {
			catchException(e);
		}
		
	}

	/**
	 * Neue View hinzufügen
	 * @param view
	 */
	public void addView(ViewInterface view) throws ControllerException {
		if (view == null){
			if (Config.DEBUG){
				SimpleLogger.log(LogLevel.DEBUG,"setting view failed");
			}
			throw new ControllerException("View not initialized!");
		}
		this.viewList.add(view);
		this.model.addObserver(view);
	}

    /**
     * getActionListener
     * Gibt eine bestehende oder ggf. eine neue Instanz von MyActionListener zurück 
     * @param action Aktion die ausgeführt werden soll
     * @return Instanz von MyActionListener
     */
    public MyActionListener getActionListener(Actions action) {

    	// Action schon in actionList enthalten?
        for (MyActionListener item : actionList) {
        	if(item.getAction() == action) {
        		return item;
        	}
        }

        // ggf. neuen actionListener anlegen
        MyActionListener actionListener = new MyActionListener(this);
        actionListener.setAction(action);

        // actionListener in die actionList eintragen
        actionList.add(actionListener);
        return actionListener;
    }

    /**
     * Setter des itemArgument
     * @param itemArgument
     */
    public void setItemArgument(Object itemArgument) {
    	this.itemArgument = itemArgument;
    }

    /**
     * Von MyActionListener ausgelöste Action
     * @param action
     */
    public void actionPerformed(Actions action) {
		if (Config.DEBUG) {
			SimpleLogger.log(LogLevel.DEBUG,"action performed:" + action);
		}

		// Action auswerten
		switch (action) {
		case GET_COUNTRIES:
			try {
				this.model.retrieveCountriesFromDB();
			} catch (Exception e) {
				catchException(e);
			}
			break;
			
		case GET_CITIES:
			System.out.println(((CountryModel) itemArgument).getCountryID());
			try {
				this.model.retrieveCitiesFromDB((CountryModel) itemArgument);
			} catch (Exception e) {
				catchException(e);
			}
			break;

		case ACTUALIZE:
		case GET_TEMPARATURE:
		case GET_WEATHER:
			try {
				this.model.retrieveWeatherFromDB((CityModel) itemArgument);
			} catch (Exception e) {
				catchException(e);
			}
			break;
			
		case GET_CURRENT_WEATHER:
			try {
				this.model.retrieveCurrentWeatherFromDB((CityModel) itemArgument);
			} catch (Exception e) {
				catchException(e);
			}
			break;

		case PRINT:
			// TODO
			JOptionPane.showMessageDialog(null, "Sorry leider noch nicht implementiert!", "Information", 
					JOptionPane.INFORMATION_MESSAGE);
			break;

		default:
			JOptionPane.showMessageDialog(null, "Unbekannte Aktion!", "Fehler", 
					JOptionPane.ERROR_MESSAGE);
			break;
		}
		itemArgument = null;
	}

    /**
     * addListener: Hinzufügen von Listeners
     * @param o
     * @param a
     */
	public void addListener(JComponent o, Actions a){
		Debug.print("Adding Listner: " + o.getClass().getName());
		if (o instanceof JComboBox){
			((JComboBox)o).addItemListener(getActionListener(a));
			((JComboBox)o).addActionListener(getActionListener(a));
		}
		if (o instanceof JButton){
			((JButton)o).addActionListener(getActionListener(a));
		}
	}
	
    /**
     * Funktion zur Anzeige von Exceptions jeglicher Art
     * @param e
     */
    private void catchException(Exception e) {
		System.out.println("Message:" + e.getMessage());
		System.out.println("Cause  :" + e.getCause());
		System.out.println("String :" + e.toString());
    }
	
}